package com.m.sms.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.m.sms.annotation.SmsLimit;
import com.m.sms.response.SmsSendResponseBody;
import com.m.sms.response.SmsSendStatus;
import com.m.sms.enums.SmsStatusEnum;
import com.m.sms.exception.ValidateParamsException;
import com.m.sms.params.SmsSendRequestBody;
import com.m.sms.service.ISmsService;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.sms.v20210111.SmsClient;
import com.tencentcloudapi.sms.v20210111.models.SendSmsRequest;
import com.tencentcloudapi.sms.v20210111.models.SendSmsResponse;
import com.tencentcloudapi.sms.v20210111.models.SendStatus;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * Description
 *
 * @Auther [li.wang@jsxfedu.com]
 * @Date 2025/3/20 13:18
 * @Version 1.0
 * @Copyright (c) 2022 京师讯飞
 */
@Slf4j
@AllArgsConstructor
public class TencentSmsServiceImpl implements ISmsService {

    private SmsClient smsClient;

    /**
     * 腾讯云官方限制批量最大支持200
     */
    private final int MAX_MOBILE_LENGTH = 200;

    private final String ZG_E164 = "+86";

    @SmsLimit(value ="#smsSendRequestBody.mobile")
    @Override
    public SmsSendResponseBody sendSms(SmsSendRequestBody smsSendRequestBody) {

        if (StrUtil.isEmpty(smsSendRequestBody.getSdkAppId())) {
            throw new ValidateParamsException("应用sdkAppId不能为空");
        }

        if (StrUtil.isEmpty(smsSendRequestBody.getSignName())) {
            throw new ValidateParamsException("短信签名不能为空");
        }

        validateParams(smsSendRequestBody);

        SendSmsRequest req = new SendSmsRequest();
        req.setSmsSdkAppId(smsSendRequestBody.getSdkAppId());
        req.setSignName(smsSendRequestBody.getSignName());
        req.setTemplateId(smsSendRequestBody.getTelId());
        //* 下发手机号码，采用 E.164 标准，+[国家或地区码][手机号]
        //* 示例如：+8613711112222， 其中前面有一个+号 ，86为国家码，13711112222为手机号，最多不要超过200个手机号 */
        //String[] phoneNumberSet = {"+8617701207932"};
        if (CollectionUtil.isNotEmpty(smsSendRequestBody.getMobileList())) {
            if (smsSendRequestBody.getMobileList().size() > MAX_MOBILE_LENGTH) {
                throw new ValidateParamsException(String.format("单次批量发送短信不能超过%s条", MAX_MOBILE_LENGTH));
            }
            req.setPhoneNumberSet(smsSendRequestBody.getMobileList().stream().map(o -> {
                if(o.startsWith(ZG_E164)){
                    return o;
                }
                return ZG_E164 + o;
            }).toArray(String[]::new));
        } else {
            req.setPhoneNumberSet(new String[]{smsSendRequestBody.getMobile().startsWith(ZG_E164) ? smsSendRequestBody.getMobile() : ZG_E164 + smsSendRequestBody.getMobile()});
        }

        /* 模板参数: 模板参数的个数需要与 TemplateId 对应模板的变量个数保持一致，若无模板参数，则设置为空 */
//        String[] templateParamSet = {"1234"};
        if(CollectionUtil.isNotEmpty(smsSendRequestBody.getTelParam())){
            req.setTemplateParamSet(smsSendRequestBody.getTelParam().values().stream().toArray(String[]::new));
        }

        try {
            SendSmsResponse res = smsClient.SendSms(req);
            log.info("腾讯云短信发送结果：{}", JSONObject.toJSONString(res));
            SmsSendResponseBody smsSendResponseBody = new SmsSendResponseBody();
            smsSendResponseBody.setRequestId(res.getRequestId());
            for (SendStatus o : res.getSendStatusSet()){
                SmsSendStatus smsSendStatus = SmsSendStatus.builder()
                        .msg(o.getMessage())
                        .mobile(o.getPhoneNumber())
                        .status("Ok".equals(o.getCode()) ? SmsStatusEnum.SUCCESS : SmsStatusEnum.FAIL)
                        .build();
                smsSendResponseBody.getSendStatusList().add(smsSendStatus);
            }
            smsSendResponseBody.setTotalCount(smsSendResponseBody.getSendStatusList().size());
            smsSendResponseBody.setFailCount((int) smsSendResponseBody.getSendStatusList().stream().filter(o -> !SmsStatusEnum.SUCCESS.equals(o.getStatus())).count());
            return smsSendResponseBody;
        } catch (TencentCloudSDKException e) {
            log.error("发送腾讯云短信失败：{} \r\n{}", e.getMessage(), e);
            throw new RuntimeException(e);
        }
    }
}
